<?
interface DB
{
	public function set_errors($msg);
	public function get_errors();
	public function is_errors();
	public function disconnect();
	
	public function query($sql);
	public function get_mysql_insert_id();
	public function fetch_array($query_id=-1,$sql=""); 
	
	public function get_array($sql);
	public function get_array_no_duplicate($sql);
	public function get_field_value($sql, $fieldName="");
	
	public function mysql_insert($table, $toAdd);
	public function mysql_update($table, $update, $where);
	
	public function db_input($str);
	public function db_input_json($str);
}
class DBmssql implements DB
{
	var $server   = DB_HOST;
	var $user     = DB_USER;
	var $pass     = DB_PASSWORD;
	var $database = DB_NAME;
	
	var $state = 0;
	var $record   = array();
	
	var $error   = "";
	var $errno   = 0;
	var $display_errors_msg = true;
	var $display_errors_query = true;
	var $field_table = "";
	var $affected_rows = 0;
	
	var $link_id  = 0;
	var $query_id = 0;
	var $errors = array();
	
	var $auto_increment_id = "";
	function __construct($defaultConnect = true, $utf8 = true) 
	{
		if($defaultConnect)
		{
			$serverName = $this->server; //serverName\instanceName
			$connectionInfo = array( "Database"=>$this->database, "UID"=>$this->user, "PWD"=>$this->pass,);
			$connectionInfo['ReturnDatesAsStrings'] = true;
			if($utf8 == true)
				$connectionInfo['CharacterSet'] = "UTF-8";
			
			$this->link_id = sqlsrv_connect( $serverName, $connectionInfo);
			
			if (!$this->link_id) 
			{
				$this->set_errors("Couldn't connect to sqlsrv");
				$this->state = 0;
			}
			else
			{
				$this->state = 1;
			}
		}
  	}
	public function query($sql, $addMessage = true) 
	{	
		$this->query_id = @sqlsrv_query($this->link_id, $sql, array(), array( "Scrollable" => SQLSRV_CURSOR_STATIC ));
		if (!$this->query_id) 
		{
			$strError = "SQL query fail: ";
			if( ($errors = sqlsrv_errors() ) != null)
			{
			   foreach( $errors as $error)
			   {
				  $strError .= "SQLSTATE: ".$error[ 'SQLSTATE']."\n";
				  $strError .= "code: ".$error[ 'code']."\n";
				  $strError .= "message: ".$error[ 'message']."\n";
			   }
			}

			if($this->display_errors_query)
				$strError .= " :: " . $sql;
			$this->set_errors($strError);
			if($this->display_errors_msg && $addMessage)
			{	
				clsErrorMessages::addMessage($strError, "error");				
			}
			$sql = "Insert into log_errors(page_name, error_name, date_created) values('".$this->db_input(selfURL())."', '".$this->db_input($strError)."', '". date("Y-m-d H:i:s") ."')";
			$this->query_id = @sqlsrv_query($this->link_id,$sql);
		}		
		if(!$this->get_errors())
		{
			if(@sqlsrv_has_rows($this->query_id))
			{
				$this->affected_rows = @sqlsrv_num_rows($this->query_id);
			}
			else
			{
				$this->affected_rows = @sqlsrv_rows_affected($this->query_id);
			}
		}
		return $this->query_id;
	}
	public function get_mysql_insert_id()
	{
		$this->auto_increment_id = $this->get_field_value("SELECT @@IDENTITY");
    	return $this->auto_increment_id;
    }
	public function get_array($sql)
	{
		$arr = array();
		$rows = $this->query($sql);			
		if($this->affected_rows > 0)
		{
		   while($row = $this->fetch_array($rows))
		   {
		   	  $arr[] = $row;
		   }
		}
		return $arr;	
	}
	public function get_array_no_duplicate($sql)
	{
		$arr = array();
		$rows = $this->query($sql);			
		if($this->affected_rows > 0)
		{
		   while($row = $this->fetch_array($rows))
		   {
			  unset($row[0]);
		   	  $arr[] = $row;
		   }
		}
		return $arr;	
	}
	public function get_field_value($sql, $fieldName="")
	{
		$rows = $this->query($sql);			
		if($this->affected_rows > 0)
		{
		   $row = $this->fetch_array($rows);
		   if($row)
		   {
				return $fieldName != "" ? $row[$fieldName] : $row[0];	
		   }
		}
		return NULL;
	}
	public function fetch_array($query_id=-1,$sql="") 
	{
		if ($query_id!=-1) 
		{
			$this->query_id=$query_id;
		}
		if ( isset($this->query_id) ) 
		{
			$this->record = @sqlsrv_fetch_array($this->query_id, SQLSRV_FETCH_BOTH);
			
		}
		else
		{
			if ( !empty($sql) ) 
			{
				$this->set_errors("Invalid query id (".$this->query_id.") on this query: $sql");
			} else 
			{
				$this->set_errors("Invalid query id ".$this->query_id." specified");
			}
		}	
		return $this->record;
	}
	public function disconnect() 
	{
		if ($this->state == 1)
		{
			sqlsrv_close($this->link_id);
			$this->state = 0;
			return 1;
		}
		return 0;
	}	
	public function set_errors($msg)
	{	
		$flagAdd = true;
		if(count($this->errors) > 0)
		{
			foreach($this->errors as $err)
			{
				if($err == $msg)
					$flagAdd = false;
			}
		}		
		if($flagAdd)
		{
			$this->errors[] = $msg . "<br>";			
		}
	}
	public function get_errors()
	{
		return $this->errors;
	}
	public function is_errors()
	{
		if($this->errors != NULL && count($this->errors) > 0)
			return true;
		return false;	
	}
	public function mysql_insert($table, $toAdd)
	{
		$fields = implode(array_keys($toAdd), ',');
		$values = "N'".implode(array_values($toAdd), "',N'")."'"; 
		$sql = 'INSERT INTO '.$table.' ('.$fields.') VALUES ('.$values.')';	
//		echo "<br>sqlsrv_insert:" . $sql;					
		return $this->query($sql); 		
	}
	public function mysql_update($table, $update, $where)
	{
		$fields = array_keys($update);
		$values = array_values($update);
		$i = 0;
		$sql = "UPDATE " . $table . " SET ";
		while(isset($fields[$i]))
		{
			if($i!=0)
			{
				$sql.=", ";
			}
			$sql .= $fields[$i] . " = '" . $values[$i] . "'";
			$i++;			
		}
		$sql .= " WHERE " . $where ;
		return $this->query($sql); 
	}	
	// SQl Injection
	function mssql_escape($data) {
        if ( !isset($data) or empty($data) ) return '';
        if ( is_numeric($data) ) return $data;

        $non_displayables = array(
            '/%0[0-8bcef]/',            // url encoded 00-08, 11, 12, 14, 15
            '/%1[0-9a-f]/',             // url encoded 16-31
            '/[\x00-\x08]/',            // 00-08
            '/\x0b/',                   // 11
            '/\x0c/',                   // 12
            '/[\x0e-\x1f]/'             // 14-31
        );
        foreach ( $non_displayables as $regex )
            $data = preg_replace( $regex, '', $data );
        $data = str_replace("'", "''", $data );
        return $data;
    }
	function db_input($str) 
	{	
		return $this->mssql_escape($str);
	}
	function db_input_json($str) 
	{	
		return $this->mssql_escape($str);
	}
}
?>